#ifndef     __EVENT_FLAGS_H
#define     __EVENT_FLAGS_H

#include "./rtos.h"
#include "../utils/assert.h"
#include "../utils/no_copyable.h"
#include "../utils/object.h"

namespace rtos {

class EventFlags : utils::no_copyable_t {

public:
    EventFlags(const char *name = "other") {
        osEventFlagsAttr_t attr;
        attr.name = name;
        attr.attr_bits = 0;
        attr.cb_mem = m_cb_mem;
        attr.cb_size = osRtxEventFlagsCbSize;
        m_id = osEventFlagsNew(&attr);
        utils::assert(m_id != NULL);
    }

    inline uint32_t set(uint32_t flags) {
        return osEventFlagsSet(m_id, flags);
    }

    inline uint32_t clr(uint32_t flags) {
        return osEventFlagsClear(m_id, flags);
    }

    inline uint32_t wait_all(uint32_t flags, uint32_t timeout = osWaitForever) {
        return osEventFlagsWait(m_id, flags, osFlagsWaitAll, timeout);
    }

    inline uint32_t wait_any(uint32_t flags, uint32_t timeout = osWaitForever) {
        return osEventFlagsWait(m_id, flags, osFlagsWaitAny, timeout);
    }

private:
    osEventFlagsId_t m_id;
    uint64_t m_cb_mem[(osRtxEventFlagsCbSize + 7) / 8];
};

namespace flags {

struct global_flags : EventFlags {};

constexpr uint32_t BLEUartTxFlag = 0x01;
constexpr uint32_t CmdUartTxFlag = 0x02;
constexpr uint32_t LogUartTxFlag = 0x04;

constexpr uint32_t R1_IDLE_FLAG = 0x08;
constexpr uint32_t R1_REQ_FLAG = 0x10;

constexpr uint32_t R2_IDLE_FLAG = 0x20;
constexpr uint32_t R2_REQ_FLAG = 0x40;

inline utils::object_t<global_flags> global;

}

}


#endif
